﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Kaleta.Network;

namespace StarWarsGame
{
    public class ATST : IEnemy
    {
        private double lastBulletTime = 0;

        private Player currentPlayer;

        public ATST(Game game, Vector3 pos, Vector3 viewPosition, Quaternion rotation, float moveSpeed, float rotationSpeed, Model enemyModel)
        {
            Game = game;
            Position = pos;
            ViewPosition = viewPosition;
            Rotation = rotation;
            MoveSpeed = moveSpeed;
            RotationSpeed = rotationSpeed;
            EnemyModel = enemyModel;
        }


        public void Draw(Matrix[] atstModelTransforms)
        {
            EnemyModel.CopyAbsoluteBoneTransformsTo(atstModelTransforms);

            Matrix worldMatrix = Matrix.CreateScale(0.0020f, 0.0020f, 0.0020f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(Rotation) * Matrix.CreateTranslation(Position);


            foreach (ModelMesh mesh in EnemyModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = atstModelTransforms[mesh.ParentBone.Index] * worldMatrix;
                    effect.View = Game.viewMatrix;
                    effect.Projection = Game.projectionMatrix;
                }
                mesh.Draw();
            }
        }


        public void UpdatePosition(GameTime gameTime, List<Player> players)
        {
            if (players.Count > 0)
            {
                GameLogic logic = new GameLogic();

                float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

                currentPlayer = players[0];
                foreach (Player player in players)
                {
                    if (Vector3.DistanceSquared(Position, player.Position) < Vector3.DistanceSquared(Position, currentPlayer.Position))
                    {
                        currentPlayer = player;
                    }
                }

                Vector3 lookVector = new Vector3(currentPlayer.Position.X, Position.Y, currentPlayer.Position.Z);

                Vector3 directionVector = Vector3.Normalize(lookVector - Position);
                Vector3 newUp = Math.Abs(Vector3.Dot(directionVector, Vector3.Up)) != 1
                              ? Vector3.Up
                              : Vector3.Cross(Vector3.Forward, directionVector);

                Matrix lookAt = Matrix.CreateWorld(Position, directionVector, newUp);
                Rotation = Quaternion.CreateFromRotationMatrix(lookAt);

                float enemyMoveSpeed = (gameTime.ElapsedGameTime.Milliseconds / 500.0f * (logic.GameSpeed)) * MoveSpeed;

                //Vector3 lastPos = MoveBackWards(_position, Rotation, enemyMoveSpeed);

                //Vector3 aimPosition = Game.xwingPosition + Game.xwingPosition - new Vector3();
                Vector3 aimPosition = currentPlayer.Position;

                MoveForward(ref _position, aimPosition, Rotation, enemyMoveSpeed);

            }
        }

        //private Vector3 MoveBackWards(Vector3 position, Quaternion rotationQuat, float speed)
        //{
        //    Vector3 addVector = new Vector3();

        //    addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);

        //    addVector.Y = 0;

        //    position += addVector * speed;

        //    return position;
        //}

        private Vector3 MoveForward(Vector3 position, Quaternion rotationQuat, float speed)
        {
            Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
            position += addVector * speed;
            return position;
        }

        private void MoveForward(ref Vector3 position, Vector3 lookAtPos, Quaternion rotationQuat, float speed)
        {
            Vector3 addVector = new Vector3();

            addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);

            addVector.Y = 0;

            position += addVector * speed;
        }

        public void Fire(GameTime gameTime)
        {
            if (currentPlayer != null)
            {
                Random random_number = new Random();
                float speed = (float)random_number.Next(30) / 100f;

                GameLogic logic = new GameLogic();
                float laserBoltSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed;
                double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
                if (currentTime - lastBulletTime > 900)
                {                            

                    Bullet newBullet = new Bullet(true);

                    // Vector3 deltaAimPosition = Game.xwingPosition - Game.xwingLastVector;
                    Vector3 deltaAimPosition = MoveForward(currentPlayer.Position, currentPlayer.Rotation, currentPlayer.MoveSpeed * 1.3f) - currentPlayer.Position;
                    Vector3 firePos = new Vector3(Position.X, Position.Y + 1.1f, Position.Z);


                    Vector3 directionVector = Vector3.Normalize(currentPlayer.Position + deltaAimPosition - firePos);
                    Vector3 newUp = Math.Abs(Vector3.Dot(directionVector, Vector3.Up)) != 1
                                  ? Vector3.Up
                                  : Vector3.Cross(Vector3.Forward, directionVector);

                    Matrix lookAt = Matrix.CreateWorld(Position, directionVector, newUp);

                    Quaternion fireRotation = Quaternion.CreateFromRotationMatrix(lookAt);

                    newBullet.bulletRotation = fireRotation;



                    //Vector3 extraFirePos = new Vector3(lookAt.Forward.X, 1.8f, lookAt.Forward.Z);

                    newBullet.bulletPosition = firePos;

                    Game.ATSTBulletList.Add(newBullet);

                    lastBulletTime = currentTime;

                    //float speed = localXwing.MoveSpeed;// (float)random_number.Next(50) / 100f;
                    //speed += .08f;
                    laserBoltSpeed = laserBoltSpeed *3.0f;
                    //Game.Laserbolts.setup_and_fire(firePos, MoveBoltForward(firePos, fireRotation, laserBoltSpeed * 100.0f), Game.randcolors.gimmie(), laserBoltSpeed, true);//, Matrix.CreateTranslation(localXwing.Position));
                    Game.Laserbolts.setup_and_fire(firePos, directionVector, Game.randcolors.gimmie(), laserBoltSpeed, false);//, Matrix.CreateTranslation(localXwing.Position));
                    


                }
            }
        }

        #region private properties

        private float _moveSpeed;
        private float _rotationSpeed;
        private Quaternion _rotation;
        private Vector3 _viewPosition;
        private Vector3 _position;
        private Game _game;
        private Model _enemyModel;

        #endregion

        #region public properties
        public Game Game
        {
            get { return _game; }
            set { _game = value; }
        }

        public float MoveSpeed
        {
            get { return _moveSpeed; }
            set { _moveSpeed = value; }
        }

        public float RotationSpeed
        {
            get { return _rotationSpeed; }
            set { _rotationSpeed = value; }
        }


        public Quaternion Rotation
        {
            get { return _rotation; }
            set { _rotation = value; }
        }

        public Vector3 ViewPosition
        {
            get { return _viewPosition; }
            set { _viewPosition = value; }
        }

        public Vector3 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public Model EnemyModel
        {
            get { return _enemyModel; }
            set { _enemyModel = value; }
        }

        #endregion
    }
}
